package com.prawn.authority.controller;

import com.prawn.authority.service.CaptchaService;
import com.prawn.authority.utils.IpAddressUtil;
import entity.Result;
import entity.StatusCode;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 控制器层
 */
@Api(tags = "图片验证码接口", description = "提供获取图片验证码的接口")
@RestController
@CrossOrigin
@RequestMapping("/captcha")
public class CaptchaController {

	@Value("${captcha.max-visit}")
	private int MAX_VISIT_NUM; // 某个时间段内刷新的最大访问次数

	@Value("${captcha.refresh-time}")
	private int REFRESH_TIME; // 指定刷新的时间段，记录访问次数

	@Value("${captcha.restrict-visit-time}")
	private int RESTRICT_VISIT_TIME; // 禁止访问验证码时间

	@Autowired
	private CaptchaService captchaService;

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 获取验证码
	 */
	@ResponseBody
	@RequestMapping(value = "/getCaptcha", method = RequestMethod.POST)
	public Result captcha(HttpServletRequest request) throws IOException {
		// 获取用户的ip地址
		String ipAdrress = IpAddressUtil.getIpAdrress(request);
		// 通过记录ip访问验证码的访问次数来进行限制，防止用户过分刷验证码
		Object visitNumInRedis = redisTemplate.opsForValue().get("verificationCode_visitNum_ip_" + ipAdrress);
		// 用户第一次获取验证码和超出约定时间内，redis中是没有访问次数的，因此获取值为null
		int visitNum = visitNumInRedis == null ? 1 : (int) visitNumInRedis + 1;
		// 判断是否已经超过了一分钟5次的限制
		if (visitNum > MAX_VISIT_NUM) {
			// 1分钟内超过了5次,禁止访问验证码
			return new Result(false, StatusCode.ERROR, "获取验证码过于频繁，请过" + RESTRICT_VISIT_TIME + "分钟后会再尝试");
		} else {
			// 1分钟内未超过了5次，进行累计
			// 获取剩余的时间
			Long expire = redisTemplate.getExpire("verificationCode_visitNum_ip_" + ipAdrress, TimeUnit.SECONDS);
			// 第一次获取的值小于0
			expire = expire < 0 ? REFRESH_TIME : expire;
			// 由于需要设置限制访问时长，因此需要判断此次访问次数是否是最大访问次数
			if (visitNum == MAX_VISIT_NUM) {
				// 此次的访问次数是'MAX_VISIT_NUM',需要把时长设置为'RESTRICT_VISIT_TIME'
				redisTemplate.opsForValue().set("verificationCode_visitNum_ip_" + ipAdrress, visitNum, RESTRICT_VISIT_TIME, TimeUnit.MINUTES);
			} else {
				redisTemplate.opsForValue().set("verificationCode_visitNum_ip_" + ipAdrress, visitNum, expire, TimeUnit.SECONDS);
			}
		}
		return new Result(true, StatusCode.OK, "验证码生成成功", captchaService.generateVerificationCode(ipAdrress));
	}
}
